import { getElement, getYHeight, getGainValue, getScale } from "./ecgPublic";
import { oQueue } from "./queue";
export default function () {
  const clearRubbish = 10
  let ctx = null

  let lineParams = {
    isStop: true,
    points_one_times: 8,
    pointX: 0
  }

  const initParams = (obj) => {
    lineParams = { ...lineParams, ...obj }
  }


  // 将所有的list都压入栈中
  const Convert16Scale = (params) => {
    params.forEach(item => {
      oQueue.EnQueue(item);
    });
  };


  // 定时走动
  const loop = async () => {
    await draw(lineParams)
    if (lineParams.isStop) {
      setTimeout(loop, 1000);
    }
    if (oQueue.IsEmpty()) {
      return;
    }
  };

  // 画波形线
  const draw = async (params) => {
    const {
      element,
      gridScale = 1,
      lineWidth = 1,
      ppm = 4, //一mm有多少个像素
      dpr = getScale(true), //屏幕缩放比
      lineData = [],
      leadValueList = [], // 每个导联值的个数值
      leadNameList = [], // 每个导联的名字
      bottomBlank = 0, // 下留白(px)
      distribution = 'between', // 分布方式
      fontSize = 12, // 字体大小
      lineColor = '#000000',// 线条色
      baseLineValue = 0, // 数据基线值(marginTop)
      startXGridLen = 0, // 每条线距离左则的网格个数
      isDrawRR = true, // 是否开启RR绘制
      ecgBeat = [], //RR数据
      speed = 25, // 走速：单位：mm/s , 每秒数据显示的长度 （25mm/s = 每秒钟数据显示成25mm 的长度）
      nFs = 250, // 采样率(nFs)：每个通道每秒钟的采样点数 (250=1秒钟250个采样点)
      duvp = 2.44,/* 采样点分辨率(duvp): 每1单位采样点代表的电压值(微伏:uV) 2.44 = (采样值为1表示电压2.44微伏，采样值100表示电压值0.244毫伏) 1mV = 1000uV */
      gain = 10, // 增益(Gain)： 单位： mm/mV, 每1mV的电压值显示的高度 (10mm/mV = 每1mV电压显示成10mm的高度)
      samplePoint = 0,//采样点总数
      isDrawLine = true, //是否开启画线
      RRLineWidth = 1, //RR间期的宽度
      canvasWidth,
      canvasHeight,
      points_one_times,
      pointX

    } = params

    if (oQueue.IsEmpty()) {
      return;
    }
    // 当当前队列中需要画的list小于设定值时，return
    if (oQueue.GetSize() < points_one_times) {
      return;
    }

    //如果x轴走完了整个画布，就从头开始画
    if (pointX >= canvasWidth) {
      pointX = 0
    }

    // 根随走动的清除线
    ctx.beginPath()
    ctx.clearRect(
      pointX + 4,
      0 - clearRubbish,
      pointX + 4 + clearRubbish,
      canvasHeight + clearRubbish,
    )
    ctx.stroke()

    // 这是个二维数据
    let useList = [];
    // 移除队列中以设定为8个的list,放到F中
    for (let J = 0; J < points_one_times; J++) {
      useList.push(oQueue.DeQueue());
    }

    let canvasElement = await getElement(element)
    const canvas = canvasElement?.node
    if (!canvas) return
    ctx = canvas.getContext('2d')
    if (!ctx) { return false }
    if (!lineData.length) return;
    if (!leadValueList.length) return;
    const width = canvasElement.width
    const height = canvasElement.height



    canvas.width = canvasWidth * dpr
    canvas.height = height * dpr
    ctx.scale(dpr, dpr)

    // 左侧距离
    const startX = ppm * startXGridLen;

    // 每个导联的个数高度[100,200,300]
    const startYList = getYHeight(
      leadValueList.length,
      height - bottomBlank,
      gridScale,
      distribution
    );

    if (isDrawLine) {
      leadValueList.forEach((item, index) => {
        ctx.lineWidth = lineWidth;
        ctx.imageSmoothingEnabled = true; // 开启图像平滑
        const startY = startYList[index] + baseLineValue;
        ctx.beginPath();
        // 画线
        drawList({
          leadIndex: index,
          data: lineData,
          ctx,
          dpr,
          startX,
          startY,
          scale: ppm,
          speed: speed,
          nFs: nFs,
          duvp: duvp,
          Gain: gain,
          gridScale,
          leadNameList: leadNameList
        });
        ctx.stroke();
      });
    }

    // 画RR(ms) RR(bpm)
    if (isDrawRR) {
      drawRR({
        data: ecgBeat,
        ctx,
        startX,
        heightY: ppm + ppm / 2,
        scale: ppm,
        speed: speed,
        nFs: nFs,
        duvp: duvp,
        Gain: gain,
        RRLineWidth: RRLineWidth,
        samplePoint: samplePoint,
        leadNameList: leadNameList,
        fontSize: fontSize / gridScale
      });
    }
  }

  const drawList = params => {
    const { leadIndex, data, startX, startY, scale, speed, nFs, duvp, Gain, ctx, leadNameList, gridScale, dpr } = params;
    data.forEach((list, N) => {
      // dx = Speed * scale /nFs, 表示1个采样点的横坐标像素值
      // dx = 走速 * 像素分辨率 / 采样率
      const dx = (speed * scale) / nFs;
      // x = x0 + dx * n
      const speedWidth = startX + dx * N * gridScale;
      // dy = duvp * scale * Gain/1000.0，表示1个采样点的纵坐标像素值
      // dy = 采样分辨率 * 像素分辨率 * 增益 / 1000
      const gain = getGainValue(Gain, leadNameList[leadIndex]);
      const dy = (duvp * scale * gain) / 1000 * gridScale;
      // y = y0 – dy * data[n];
      const speedHeight = startY - dy * data[N][leadIndex];
      // 画线
      ctx.lineTo(speedWidth, speedHeight);
    });
  };

  const drawRR = params => {
    const { data, startX, heightY, RRLineWidth, scale, speed, nFs, ctx, fontSize } = params;
    if (!data?.length) return;
    ctx.beginPath();
    ctx.lineWidth = RRLineWidth;
    ctx.imageSmoothingEnabled = true;
    const _data = data.sort((a, b) => a.lPos - b.lPos);
    _data.forEach(item => {
      const dx = (speed * scale) / nFs;
      const speedWidth = startX + dx * item.lPos;
      ctx.moveTo(speedWidth, 0);
      ctx.lineTo(speedWidth, heightY);

      if (item.RR > 0) {
        const distance = (startX + dx * item.RR) / 2;
        const fontWidth = speedWidth - distance;
        ctx.textAlign = "center"; // 设置文本居中
        ctx.font = `500 ${fontSize}px Microsoft YaHei`;
        ctx.fillText(item.RR, fontWidth, scale * 2.6);
        const RRbpm = Math.floor(60000 / item.RR + 0.5);
        ctx.fillText(RRbpm, fontWidth, scale * 5.4);
      }
    });
    ctx.stroke();
  };

  // 获取实际波形线需要渲染的长度
  const getLineWidth = (params) => {
    const { speed = 25, ppm = 4, nFs = 250, lineData = [], gridScale = 1 } = params
    const dx = (speed * ppm) / nFs;
    const N = lineData.length;
    const lastWidth = dx * N * gridScale;
    return lastWidth + ppm * 1;
  };

  return {
    draw,
    getLineWidth,
    Convert16Scale,
    loop,
    initParams
  }
}
